home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / MacApp Release 10 / MacApp Release 10 - HD Ready / Libraries / Core / Sources / UGeometry.cp < prev    next >
Encoding:
Text File  |  1996-04-03  |  12.8 KB  |  444 lines  |  [TEXT/MPS ]

  1. //----------------------------------------------------------------------------------------
  2. // UGeometry.cp 
  3. // Copyright © 1987-96 by Apple Computer, Inc. All rights reserved.
  4. //----------------------------------------------------------------------------------------
  5.  
  6. #ifndef __UGEOMETRY__
  7. #include "UGeometry.h"
  8. #endif
  9.  
  10. // MacApp
  11.  
  12. #ifndef __MACAPPTYPES__
  13. #include "MacAppTypes.h"
  14. #endif
  15.  
  16. // ANSI
  17.  
  18. #ifndef __LIMITS__
  19. #include <limits.h>
  20. #endif
  21.  
  22. #ifndef __STDIO__
  23. #include <stdio.h>
  24. #endif
  25.  
  26. #pragma segment MAGeometryRes
  27. //========================================================================================
  28. // VPoint method definitions
  29. //========================================================================================
  30.  
  31. //----------------------------------------------------------------------------------------
  32. // Conversion method for converting a VPoint to a CPoint. Note that a newly
  33. // allocated CPoint is returned. We are not just viewing a VPoint as a CPoint.
  34. //----------------------------------------------------------------------------------------
  35.  
  36. CPoint VPoint::ToPoint() const
  37. {
  38.     return CPoint((short) MinMax(SHRT_MIN, h, SHRT_MAX), (short) MinMax(SHRT_MIN, v, SHRT_MAX));
  39. }
  40.  
  41.  
  42. //----------------------------------------------------------------------------------------
  43. // Arithmatic operators for VPoint. Addition and subtraction are all that make
  44. // any sense. Both the Add and AddTo forms are defined.
  45. //----------------------------------------------------------------------------------------
  46. VPoint VPoint::operator+(const VPoint& pt) const
  47. {
  48.     return VPoint(h + pt.h, v + pt.v);
  49. }
  50.  
  51. VPoint VPoint::operator-(const VPoint& pt) const
  52. {
  53.     return VPoint(h - pt.h, v - pt.v);
  54. }
  55.  
  56. VPoint VPoint::operator-() const
  57. {
  58.     return VPoint(-h, -v);
  59. }
  60.  
  61. VPoint& VPoint::operator+=(const VPoint& pt)
  62. {
  63.     v += pt.v;
  64.     h += pt.h;
  65.     return *this;
  66. }
  67.  
  68. VPoint& VPoint::operator-=(const VPoint& pt)
  69. {
  70.     v -= pt.v;
  71.     h -= pt.h;
  72.     return *this;
  73. }
  74.  
  75.  
  76. //----------------------------------------------------------------------------------------
  77. // Relational operators for VPoint. These are defined by applying the operator in
  78. // question to both coordinates. The condition must hold for both to hold for the
  79. // VPoints the corresponding VPoints.
  80. //----------------------------------------------------------------------------------------
  81.  
  82. Boolean VPoint::operator!=(const VPoint& pt) const
  83. {
  84.     return v != pt.v || h != pt.h;
  85. }
  86.  
  87. Boolean VPoint::operator==(const VPoint& pt) const
  88. {
  89.     return v == pt.v && h == pt.h;
  90. }
  91.  
  92. Boolean VPoint::operator>(const VPoint& pt) const
  93. {
  94.     return v > pt.v && h > pt.h;
  95. }
  96.  
  97. Boolean VPoint::operator<(const VPoint& pt) const
  98. {
  99.     return v < pt.v && h < pt.h;
  100. }
  101.  
  102. Boolean VPoint::operator>=(const VPoint& pt) const
  103. {
  104.     return v >= pt.v && h >= pt.h;
  105. }
  106.  
  107. Boolean VPoint::operator<=(const VPoint& pt) const
  108. {
  109.     return v <= pt.v && h <= pt.h;
  110. }
  111.  
  112.  
  113. //----------------------------------------------------------------------------------------
  114. // Some useful methods to send to VPoints.
  115. //----------------------------------------------------------------------------------------
  116.  
  117. void VPoint::ConstrainTo(const VRect& rt)
  118. {
  119.     // If this CPoint is not inside 'rt' then move it to the nearest edge.
  120.     
  121.     if (v < rt.top)
  122.         v = rt.top;
  123.     if (v > rt.bottom)
  124.         v = rt.bottom;
  125.     if (h < rt.left)
  126.         h = rt.left;
  127.     if (h > rt.right)
  128.         h = rt.right;
  129. }
  130.  
  131.  
  132. //========================================================================================
  133. // VRect method definitions
  134. //========================================================================================
  135.  
  136. //----------------------------------------------------------------------------------------
  137. // Conversion method for converting a VRect to a CRect. Note that a newly allocated CRect
  138. // is returned. We are not just viewing a VRect as a CRect. Also a constructor for
  139. // constructing a VRect from a CRect.
  140. //----------------------------------------------------------------------------------------
  141.  
  142. CRect VRect::ToRect() const
  143. {
  144.     return CRect((short) MinMax(SHRT_MIN, left, SHRT_MAX),
  145.         (short) MinMax(SHRT_MIN, top, SHRT_MAX),
  146.         (short) MinMax(SHRT_MIN, right, SHRT_MAX),
  147.         (short) MinMax(SHRT_MIN, bottom, SHRT_MAX));
  148. }
  149.  
  150. //----------------------------------------------------------------------------------------
  151. // Operators for adding and subtracting one VRect from to/ from another. Both the Add and
  152. // AddTo form of operators are defined.
  153. //----------------------------------------------------------------------------------------
  154.  
  155. VRect VRect::operator+(const VRect& rt) const
  156. {
  157.     return VRect(left + rt.left, top + rt.top, right + rt.right, bottom + rt.bottom);
  158. }
  159.  
  160. VRect VRect::operator-(const VRect& rt) const
  161. {    
  162.     return VRect(left - rt.left, top - rt.top, right - rt.right, bottom - rt.bottom);
  163. }
  164.  
  165. VRect& VRect::operator+=(const VRect& rt)
  166. {
  167.     top += rt.top;
  168.     left+= rt.left;
  169.     bottom += rt.bottom;
  170.     right += rt.right;
  171.     
  172.     return *this;
  173. }
  174.  
  175.  
  176. VRect& VRect::operator-=(const VRect& rt)
  177. {
  178.     top -= rt.top;
  179.     left-= rt.left;
  180.     bottom-= rt.bottom;
  181.     right-= rt.right;
  182.     
  183.     return *this;
  184. }
  185.  
  186.  
  187. //----------------------------------------------------------------------------------------
  188. // Operators for adding and subtracting a VPoint to/ from a VRect. A VPoint is added to a
  189. // VRect by adding the VPoint to both the top-left and bottom-right VPoints that define
  190. // the VRect. Both the Add and AddTo operators are defined. Very convenient for
  191. // translating VRects. These take a CPoint and since VPoint has a constructor that takes
  192. // two VCoordinates the VRect windowRect can be translated 100 pixels in the positive y
  193. // direction by the statement:
  194. //
  195. //    windowRect = windowRect + VPoint (0, 100);    or
  196. //     windowRect += VPoint (0, 100);
  197. //----------------------------------------------------------------------------------------
  198.  
  199. VRect VRect::operator+(const VPoint& pt) const
  200. {
  201.     return VRect(left + pt.h, top + pt.v, right + pt.h, bottom + pt.v);
  202. }
  203.  
  204. VRect VRect::operator-(const VPoint& pt) const
  205. {
  206.     return VRect(left - pt.h, top - pt.v, right - pt.h, bottom - pt.v);
  207. }
  208.  
  209. VRect VRect::operator-() const
  210. {
  211.     return VRect(-left, -top, -right, -bottom);
  212. }
  213.  
  214. VRect& VRect::operator+=(const VPoint& pt)
  215. {
  216.     top += pt.v;
  217.     left+= pt.h;
  218.     bottom+= pt.v;
  219.     right+= pt.h;
  220.     
  221.     return *this;
  222. }
  223.  
  224. VRect& VRect::operator-=(const VPoint& pt)
  225. {
  226.     top -= pt.v;
  227.     left -= pt.h;
  228.     bottom -= pt.v;
  229.     right -= pt.h;
  230.     
  231.     return *this;
  232. }
  233.  
  234.  
  235. //----------------------------------------------------------------------------------------
  236. // Inset a VRect using the coordinates in VPoint for the inset delta
  237. //----------------------------------------------------------------------------------------
  238.  
  239. VRect& VRect::Inset(const VPoint& delta)
  240. {
  241.     top += delta.v;
  242.     left += delta.h;
  243.     bottom -= delta.v;
  244.     right -= delta.h;
  245.     
  246.     return *this;
  247. }
  248.  
  249.  
  250. //----------------------------------------------------------------------------------------
  251. // Equality operators, other relational operator could be defined such as <. But their
  252. // meaning is ambiguous and probably better implemented as methods. For example, aRect <
  253. // bRect could return true if aRect was inside of bRect, or could return true if the area
  254. // of aRect was less than the area of bRect.
  255. //----------------------------------------------------------------------------------------
  256.  
  257. Boolean VRect::operator==(const VRect& rt) const
  258. {
  259.     return
  260.         top == rt.top && left == rt.left &&
  261.         bottom == rt.bottom && right == rt.right;
  262. }
  263.  
  264. Boolean VRect::operator!=(const VRect& rt) const
  265. {
  266.     return
  267.         top != rt.top || left != rt.left ||
  268.         bottom != rt.bottom || right != rt.right;
  269. }
  270.  
  271.  
  272. //----------------------------------------------------------------------------------------
  273. // Two simple area operators, the intersection & and the union ||. The definition of union
  274. // here is to return a VRect that exactly encloses its operands.
  275. //----------------------------------------------------------------------------------------
  276.  
  277. VRect VRect::operator &(const VRect& rt) const
  278. {
  279.     VRect returnRect(Max(left, rt.left), Max(top, rt.top), Min(right, rt.right), Min(bottom, rt.bottom));
  280.     
  281.     if (!returnRect.Valid())
  282.         returnRect.top = returnRect.left = returnRect.bottom = returnRect.right = 0;
  283.     
  284.     return VRect(returnRect);
  285. }
  286.  
  287. VRect VRect::operator |(const VRect& rt) const
  288. {
  289.     return VRect(Min(left, rt.left), Min(top, rt.top), Max(right, rt.right), Max(bottom, rt.bottom));
  290. }
  291.  
  292.  
  293. //----------------------------------------------------------------------------------------
  294. // Returns true if a valid rectangle (left < right and top < bottom). If not a valid
  295. // rectangle then return false and set all coordinates to 0.
  296. //----------------------------------------------------------------------------------------
  297.  
  298. Boolean VRect::Valid() const
  299. {
  300.     return left <= right && top <= bottom;
  301. }
  302.  
  303.  
  304. //----------------------------------------------------------------------------------------
  305. // Fix up coordinates so that left <= right and top <= bottom.
  306. //----------------------------------------------------------------------------------------
  307.  
  308. void VRect::Validate()
  309. {
  310.     if (top > bottom)
  311.     {
  312.         VCoordinate tmp = top;
  313.         top = bottom;
  314.         bottom = tmp;
  315.     }
  316.     if (left > right)
  317.     {
  318.         VCoordinate tmp = left;
  319.         left = right;
  320.         right = tmp;
  321.     }
  322. }
  323.  
  324.  
  325. //----------------------------------------------------------------------------------------
  326. // Empty returns true if the rectangle is empty.
  327. //----------------------------------------------------------------------------------------
  328.  
  329. Boolean VRect::Empty() const
  330. {
  331.     return right <= left || bottom <= top;
  332. }
  333.  
  334.  
  335. //----------------------------------------------------------------------------------------
  336. // GetLength returns the length of a VRect in a given dimension.
  337. //----------------------------------------------------------------------------------------
  338.  
  339. VCoordinate VRect::GetLength(VHSelect sel) const
  340. {
  341.     return (sel == vSel) ? (bottom - top) : (right - left);
  342. }
  343.  
  344.  
  345. //----------------------------------------------------------------------------------------
  346. // GetSize returns the size of a VRect as a VPoint.
  347. //----------------------------------------------------------------------------------------
  348. VPoint VRect::GetSize() const
  349. {
  350.     return VPoint(right - left, bottom - top);
  351. }
  352.  
  353. //----------------------------------------------------------------------------------------
  354. // The Contains method takes either a VPoint or a VRect and returns true if the operand is
  355. // inside of the VRect the method is applied to.
  356. //----------------------------------------------------------------------------------------
  357.  
  358. Boolean VRect::Contains (const VPoint& pt) const
  359. {
  360.     // Does the CPoint 'pt' lie within the rectangle of 'this'?
  361.     
  362.     return pt.v >= top && pt.v < bottom && pt.h >= left && pt.h < right;
  363. }
  364.  
  365. Boolean VRect::Contains (const VRect& rt) const
  366. {
  367.     // Does the rectangle 'rt' lie withing the rectagle of 'this'?
  368.     
  369.     return rt.top >= top && rt.bottom <= bottom && rt.left >= left && rt.right <= right;
  370. }
  371.  
  372. //========================================================================================
  373. // The following global routines were originally for Pascal compatibility. They are basically
  374. // wrappers that call back into the methods in VRect and VPoint. C++ programs should use
  375. // the methods in VRect and VPoint to avoid the additional function call overhead.
  376. //
  377. // Left in for compatibility.
  378. //========================================================================================
  379.  
  380. void PtToVPt(const CPoint thePt, VPoint& theVPt)
  381. { theVPt = VPoint(thePt); }
  382.  
  383. CPoint VPtToPt(const VPoint& theVPt)
  384. { return theVPt.ToPoint(); }
  385.  
  386. void RectToVRect(const CRect& theRect, VRect& theVRect)
  387. { theVRect = VRect(theRect); }
  388.  
  389. void VRectToRect(const VRect& theVRect, CRect& theRect)
  390. { theRect = theVRect.ToRect(); }
  391.  
  392. void AddVPt(const VPoint& srcVPt, VPoint& dstVPt)
  393. { dstVPt += srcVPt; }
  394.  
  395. void SubVPt(const VPoint& srcVPt, VPoint& dstVPt)
  396. { dstVPt -= srcVPt; }
  397.  
  398. void SetVPt(VPoint& vPt, VCoordinate h, VCoordinate v)
  399. { vPt = VPoint(h, v); }
  400.  
  401. Boolean EqualVPt(const VPoint& aVPt, const VPoint& bVPt)
  402. { return aVPt == bVPt; }
  403.  
  404. void SetVRect(VRect& vRt,
  405.               VCoordinate left, VCoordinate top,
  406.               VCoordinate right, VCoordinate bottom)
  407. { vRt = VRect(left, top, right, bottom); }
  408.  
  409. void OffsetVRect(VRect& vRt, VCoordinate dh, VCoordinate dv)
  410. { vRt += VPoint(dh, dv); }
  411.  
  412. void InsetVRect(VRect& vRt, VCoordinate dh, VCoordinate dv)
  413. { vRt.Inset(VPoint(dh, dv)); }
  414.  
  415. void Pt2VRect(const VPoint& theTopLeft, const VPoint& theBotRight, VRect& vRt)
  416. { vRt = VRect(theTopLeft, theBotRight); }
  417.  
  418. Boolean PtInVRect(const VPoint& vPt, const VRect& vRt)
  419. { return vRt.Contains(vPt); }
  420.  
  421. Boolean EmptyVRect(const VRect& vRt)
  422. { return vRt.Empty(); }
  423.  
  424. Boolean EqualVRect(const VRect& aVRt, const VRect& bVRt)
  425. { return aVRt == bVRt; }
  426.  
  427. VCoordinate LengthVRect(const VRect& vRt, VHSelect whichDim)
  428. { return vRt.GetLength(whichDim); }
  429.  
  430. void PinVRect(const VRect& vRt, VPoint& vPt)
  431. { vPt.ConstrainTo(vRt); }
  432.  
  433. Boolean SectVRect(const VRect& src1, const VRect& src2, VRect& dst)
  434. {    dst = src1 & src2; return !dst.Empty(); }
  435.  
  436. void UnionVRect(const VRect& src1, const VRect& src2, VRect& dst)
  437. { dst = src1 | src2; }
  438.  
  439.  
  440. //----------------------------------------------------------------------------------------
  441. // End of UGeometry.cp
  442.  
  443. #pragma segment Inline
  444.